"""
用户视图层
"""

import time
import re
from interface import user_interface, bank_interface, shop_interface
from lib import common
from core import admin


logged_user = None
logged_admin = False


# 退出
def out():
    print("\n感谢使用购物管理系统！")
    time.sleep(1)
    exit()  # exit()函数用于退出程序


# 注册
def sign_up(is_admin=False):
    while True:
        print("\n注册")
        username = input("请输入用户名：").strip()
        password = input("请输入密码：").strip()
        password_confirm = input("请确认密码：").strip()
        is_register = input("按任意键确认/n退出：").strip().lower()

        if is_register == "exit":
            break

        if password != password_confirm:
            print("两次输入的密码不一致，请重新输入！")
            continue

        # 校验用户名是否合法
        if not re.findall(r"^[a-zA-Z0-9_-]{3,12}$", username):
            # findall()函数用于查找字符串中所有匹配正则表达式的子串，并返回一个列表
            # 正则表达式：^[a-zA-Z0-9_-]{3,12}$ 匹配用户名，用户名必须由字母、数字、下划线、减号组成，长度在3-12位之间
            print("用户名必须由字母、数字、下划线、减号组成，长度在3-12位之间！")
            continue

        # 校验密码强度
        if not re.findall(r"^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,16}$", password):
            # 正则表达式：^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,16}$ 匹配密码，密码必须包含大小写字母、数字，长度在8-16位之间
            print("密码必须包含大小写字母、数字，长度在8-16位之间！")
            continue

        # 调用函数对密码进行加密
        password = common.pwd_to_sha256(password)

        # 调用逻辑接口层的接口进行注册
        flag, msg = user_interface.register_interface(username, password, is_admin)
        print(msg)
        if flag:
            break


# 登录
def sign_in():
    while True:
        # 输入用户名
        username = input("请输入用户名：").strip()

        # 输入密码
        password = input("请输入密码：").strip()

        is_login = (
            input("按任意键确认/n退出：").strip().lower()
        )  # /n是换行符，lower()是将输入转为小写

        if is_login == "exit":
            break

        # 调用函数对密码进行加密
        password = common.pwd_to_sha256(password)

        # 调用逻辑接口层的接口进行登录
        flag, msg, is_admin = user_interface.login_interface(username, password)
        print(msg)
        if flag:
            global logged_user, logged_admin
            logged_user = username
            logged_admin = is_admin
            break


# 充值
@common.login_auth
def recharge(username=None):
    while True:
        # 输入充值金额
        recharge_amount = input("请输入充值金额：").strip()

        is_recharge = input("按任意键确认/n退出：").strip().lower()

        if is_recharge == "exit":
            break

        # 判断用户输入的金额是否为数字
        if not recharge_amount.isdigit():
            print("请输入数字金额！")
            continue

        # 将recharge_amount转为int类型
        recharge_amount = int(recharge_amount)

        # 判断用户输入的金额是否大于0
        if recharge_amount <= 0:
            print("充值金额必须大于0！")
            continue

        if username == None:
            username = logged_user

        # 调用逻辑接口层的接口进行充值
        flag, msg = bank_interface.recharge_interface(username, recharge_amount)
        print(msg)
        if flag:
            break


# 转账
@common.login_auth
def transfer():
    while True:
        print("\n转账")

        # 接收用户输入的转账用户名和金额
        transfer_username = input("转给谁：").strip()
        transfer_amount = input("转多少：").strip()
        is_transfer = input("按任意键确认/n退出：").strip().lower()

        if is_transfer == "exit":
            break

        # 判断用户输入的金额是否为数字
        if not transfer_amount.isdigit():
            print("请输入数字金额！")
            continue

        # 将transfer_amount转为int类型
        transfer_amount = int(transfer_amount)

        # 判断用户输入的金额是否大于0
        if transfer_amount <= 0:
            print("转账金额必须大于0！")
            continue

        # 判断是否给自己转账
        if transfer_username == logged_user:
            print("不能转账给自己！")
            continue

        # 调用逻辑接口层的接口进行转账
        flag, msg = bank_interface.transfer_interface(
            logged_user, transfer_username, transfer_amount
        )
        print(msg)
        if flag:
            break


# 提现
@common.login_auth
def withdraw():
    while True:
        print("\n提现")
        # 输入提现金额
        recharge_amount = input("请输入提现金额：").strip()

        is_withdraw = input("按任意键确认/n退出：").strip().lower()

        if is_withdraw == "exit":
            break

        # 判断用户输入的金额是否为数字
        if not recharge_amount.isdigit():
            print("请输入数字金额！")
            continue

        # 将recharge_amount转为int类型
        recharge_amount = int(recharge_amount)

        # 判断用户输入的金额是否大于500
        if recharge_amount < 500:
            print("提现金额不能少于500！")
            continue

        # 调用逻辑接口层的接口进行提现
        flag, msg = bank_interface.withdraw_interface(logged_user, recharge_amount)
        print(msg)
        if flag:
            break


# 查看余额
@common.login_auth
def check_balance():
    flag, msg = bank_interface.check_balance_interface(logged_user)
    print(msg)
    input("按任意键退出...")


# 查看流水
@common.login_auth
def check_records():
    flag, msg = bank_interface.check_records_interface(logged_user)
    if not msg:
        print("暂无流水记录！")
    for record in msg:
        print(record)
    input("按任意键退出...")


# 购物
@common.login_auth
def shopping():

    # 初始化一个购物车
    shopping_cart = {}

    # 调用逻辑接口层获取商品列表
    goods_list = shop_interface.get_goods_list_interface("goods")

    if not goods_list:
        print("暂无商品！")
        return

    while True:
        print("欢迎来到购物商城！".center(30, "="))
        # enumerate()函数用于将列表转换为索引-元素对，并返回一个enumerate对象
        for index, good in enumerate(goods_list):
            print(f"{index+1} --- {good}")
        print("24小时为您服务".center(30, "="))

        choice = input("请输入商品序号（exit：退出/y：结算）：").strip().lower()

        if choice == "exit":
            if not shopping_cart:
                break
            else:
                flag, msg = shop_interface.add_shopping_cart_interface(
                    logged_user, shopping_cart
                )
                print(msg)
                if flag:
                    break

        if choice == "y":
            if not shopping_cart:
                print("购物车为空！无法结算！")
                continue
            else:
                flag, msg, total_price = (
                    shop_interface.settlement_shopping_cart_interface(
                        logged_user, shopping_cart
                    )
                )
                print(msg)
                if flag:
                    print(f"总价：{total_price}")
                    break
                break

        # 判断用户输入的是否是数字
        if not choice.isdigit():
            print("请输入数字序号！")
            continue

        # 将choice转为int类型
        choice = int(choice)

        # 判断用户输入的序号是否存在
        opt = choice - 1
        if opt not in range(len(goods_list)):
            print("该商品不存在！")
            continue

        # 获取用户选择的商品信息
        good_info = goods_list[opt]
        name = good_info.get("name")

        # 把商品信息添加到购物车
        # 判断商品是否已经在购物车中
        if name not in shopping_cart:
            good_info["数量"] = 1
            shopping_cart[name] = good_info
        else:
            shopping_cart[name]["数量"] += 1

        # 显示购物车
        for index, good in enumerate(shopping_cart.values()):
            print(f"{index+1} --- {good['name']} x {good['数量']}")


# 查看购物车
@common.login_auth
def check_shopping_cart():

    # 调用逻辑接口层获取购物车信息
    msg_1 = shop_interface.get_shopping_cart_interface(logged_user)
    if not msg_1:
        print("购物车为空！")
        input("按任意键退出...")
        return

    for index, good in enumerate(msg_1.values()):
        print(f"{index+1} --- {good['name']} x {good['数量']}")

    # 去掉购物车中的商品
    while True:
        good_name = (
            input("请输入需要的操纵（exit：退出/d：删除/y：结算）：").strip().lower()
        )
        if good_name == "exit":
            break

        elif good_name == "d":
            if good_name in msg:
                # 调用逻辑接口层，对购物车中的商品进行删除
                shop_interface.delete_shopping_cart_interface(logged_user, good_name)
                break
            else:
                print("该商品不存在！")
                input("按任意键退出...")
                break
        elif good_name == "y":
            # 调用逻辑接口层，对购物车中的商品进行结算
            flag, msg, total_price = shop_interface.settlement_shopping_cart_interface(
                logged_user, msg_1
            )
            print(msg)
            if flag:
                print(f"总价：{total_price}")
                for index, good in enumerate(msg_1.values()):
                    shop_interface.delete_shopping_cart_interface(
                        logged_user, good["name"]
                    )
                break
            break
        else:
            print("输入有误，退出！")
            break


# 退出账号
@common.login_auth
def sign_out():

    global logged_user, logged_admin
    print(f"您已退出账号：{logged_user}！")
    logged_user = None
    logged_admin = False


# 管理员功能
@common.login_auth
def admin_function():

    admin.main()


# 函数字典
function_dict = {
    "0": ("退出", out),
    "1": ("注册", sign_up),
    "2": ("登录", sign_in),
    "3": ("充值", recharge),
    "4": ("转账", transfer),
    "5": ("提现", withdraw),
    "6": ("查看余额", check_balance),
    "7": ("查看流水", check_records),
    "8": ("购物", shopping),
    "9": ("购物车", check_shopping_cart),
    "10": ("退出账号", sign_out),
    "11": ("管理员功能", admin_function),
}


# 主程序
def main():
    while True:
        print("购物管理系统".center(30, "="))

        for num in function_dict:
            if logged_admin:
                print(f"{num} --- {function_dict[num][0]}".ljust(30, " "))
            else:
                if num != "11":
                    print(f"{num} --- {function_dict[num][0]}".ljust(30, " "))

        print("我是有底线的".center(30, "="))

        choice = input("您要进入的功能编号：").strip()

        if choice not in function_dict or (not logged_admin and choice == "11"):
            print("输入有误，请重新输入！")
            continue

        function_dict.get(choice)[1]()
